#pragma once
#include <atomic>
#include <vector>
#include <thread>

class RingBuffer {
public:
    RingBuffer(size_t capacity) 
        : capacity_(capacity), buffer_(capacity), read_pos_(0), write_pos_(0) {}
    
    bool Write(const uint8_t* data, size_t len) {
        size_t free_space = GetFreeSpace();
        if (free_space < len) return false;
        
        size_t first_part = std::min(len, capacity_ - write_pos_);
        if (first_part > 0) {
            std::copy(data, data + first_part, buffer_.begin() + write_pos_);
            write_pos_ = (write_pos_ + first_part) % capacity_;
        }
        
        size_t second_part = len - first_part;
        if (second_part > 0) {
            std::copy(data + first_part, data + len, buffer_.begin());
            write_pos_ = second_part;
        }
        return true;
    }
    
    size_t Read(uint8_t* dest, size_t max_len) {
        size_t avail = GetAvailableSize();
        if (avail == 0) return 0;
        
        size_t to_read = std::min(avail, max_len);
        size_t first_part = std::min(to_read, capacity_ - read_pos_);
        
        if (first_part > 0) {
            std::copy(buffer_.begin() + read_pos_, 
                      buffer_.begin() + read_pos_ + first_part, 
                      dest);
            read_pos_ = (read_pos_ + first_part) % capacity_;
        }
        
        size_t second_part = to_read - first_part;
        if (second_part > 0) {
            std::copy(buffer_.begin(), 
                      buffer_.begin() + second_part, 
                      dest + first_part);
            read_pos_ = second_part;
        }
        return to_read;
    }
    
    size_t GetAvailableSize() const {
        if (write_pos_ >= read_pos_) 
            return write_pos_ - read_pos_;
        return capacity_ - read_pos_ + write_pos_;
    }
    
    size_t GetFreeSpace() const {
        return capacity_ - GetAvailableSize() - 1; // 保留一个空位
    }

private:
    const size_t capacity_;
    std::vector<uint8_t> buffer_;
    size_t read_pos_;
    size_t write_pos_;
};